package com.eveinfo.update;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.os.Handler;

import com.eveinfo.EveInfo;
import com.eveinfo.api.accessors.Certificates;
import com.eveinfo.api.accessors.CharacterSheet;
import com.eveinfo.api.accessors.CharacterTraining;
import com.eveinfo.api.accessors.SkillQueue;
import com.eveinfo.api.accessors.Skills;
import com.eveinfo.api.character.sheet.ApiSheet;
import com.eveinfo.api.character.skilltraining.ApiSkillTraining;
import com.eveinfo.api.utils.skilllist.ApiSkills;
import com.eveinfo.tools.Logging;
import com.eveinfo.tools.Pilot;

public class EveInfoData {

	@SuppressWarnings("unused")
	private final Context context;

	private final List<CharacterData> characterDatas;
	private ProgressDialog progressDialog;

	private Certificates certificates;
	private ApiSkills skills;

	private Handler handler = new Handler();
	private Thread certificatesThread;
	private Thread skillsThread;
	private Thread sheetThread;

	private List<DataChangedListener> listeners;

	public EveInfoData(Context context) {
		this.context = context;
		this.characterDatas = Collections.synchronizedList(new ArrayList<CharacterData>());
		this.listeners = Collections.synchronizedList(new ArrayList<DataChangedListener>());

		progressDialog = ProgressDialog.show(context, "", "Loading. Please wait...");
		initSkills();
		progressDialog.setOnDismissListener(new OnDismissListener() {
			@Override
			public void onDismiss(DialogInterface dialog) {
				initCertificates();
				initCharacters();
				datasChanged();
			}
		});
	}

	public void update() {
		initCharacters();
		datasChanged();
	}

	public List<CharacterData> getCharacterDatas() {
		return characterDatas;
	}

	public void setDataChangedListener(DataChangedListener listener) {
		listeners.add(listener);
	}

	private void datasChanged() {
		final int size = listeners.size();
		for (int i = 0; i < size; i++) {
			DataChangedListener listener = listeners.get(i);
			listener.datasChanged(characterDatas);
		}
	}

	/*
	 * Initialisation
	 */

	private void initSkills() {
		progressDialog.show();
		skillsThread = new Thread() {
			public void run() {
				try {
					skills = Skills.getInstance().getSkills();
				} catch (Exception e) {
					e.printStackTrace();
					// traiter l'erreur
				}
				progressDialog.dismiss();
			}
		};
		skillsThread.setPriority(2);
		skillsThread.start();
	}

	private void initCertificates() {
		certificatesThread = new Thread() {
			public void run() {
				try {
					certificates = Certificates.getInstance();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		};
		certificatesThread.setPriority(1);
		certificatesThread.start();
	}

	private void initCharacters() {
		sheetThread = new Thread() {
			public void run() {
				try {
					List<Pilot> pilots = EveInfo.getPilots();
					for (Pilot pilot : pilots) {
						final int userId = pilot.getUserId();
						final String apiKey = pilot.getApiKey();
						final int characterId = pilot.getCharacterId();
						CharacterData characterData = getCharacterData(characterId);
						if (characterData == null) {
							characterData = new CharacterData();
							characterDatas.add(characterData);
						}
						CharacterSheet character = new CharacterSheet(userId, characterId, apiKey);
						final ApiSheet sheet = character.getApiSheet();
						sheet.setUserId(userId);
						sheet.setApiKey(apiKey);
						sheet.setCharacterID(characterId);
						characterData.setSheet(sheet);
						initSkillTraining(characterId);
						initSkillQueue(characterId);
						handler.post(new Runnable() {
							@Override
							public void run() {
								datasChanged();
							}
						});
					}
				} catch (NumberFormatException e) {
					e.printStackTrace();
					Logging.getInstance().e(e);
					// AlertDialog.Builder builder = new
					// AlertDialog.Builder(context);
					// builder.setMessage("Wrong Api Key or User ID");
					// builder.show();
				} catch (Exception e) {
					e.printStackTrace();
					Logging.getInstance().e(e);
					// AlertDialog.Builder builder = new
					// AlertDialog.Builder(context);
					// builder.setMessage(e.getMessage());
					// builder.show();
				}
			}
		};
		sheetThread.setPriority(4);
		sheetThread.start();
	}

	private void initSkillTraining(final int characterId) {
		Thread thread = new Thread() {
			public void run() {
				try {
					try {
						sheetThread.join();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					CharacterData character = getCharacterData(characterId);
					ApiSheet sheet = character.getSheet();
					final ApiSkillTraining apiTraining = new CharacterTraining(sheet.getUserId(), sheet
							.getCharacterID(), sheet.getApiKey()).getApiTraining();
					character.setSkillTraining(apiTraining);
					handler.post(new Runnable() {
						@Override
						public void run() {
							datasChanged();
						}
					});
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		};
		thread.setPriority(3);
		thread.start();

	}

	private void initSkillQueue(final int characterId) {
		Thread thread = new Thread() {
			public void run() {
				try {
					try {
						sheetThread.join();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					CharacterData character = getCharacterData(characterId);
					ApiSheet sheet = character.getSheet();
					final SkillQueue skillQueue = new SkillQueue(sheet.getUserId(), sheet.getCharacterID(), sheet
							.getApiKey());
					character.setSkillQueue(skillQueue);
					handler.post(new Runnable() {
						@Override
						public void run() {
							datasChanged();
						}
					});
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		};
		thread.setPriority(2);
		thread.start();

	}

	/*
	 * Getter
	 */

	public Certificates getCertificates() {
		try {
			certificatesThread.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return certificates;
	}

	public ApiSkills getSkills() {
		return skills;
	}

	public CharacterData getCharacterData(int characterID) {
		final List<CharacterData> characterDatas = this.characterDatas;
		final int size = characterDatas.size();
		for (int i = 0; i < size; i++) {
			CharacterData character = characterDatas.get(i);
			if (character.getSheet().getCharacterID() == characterID) {
				return character;
			}
		}
		return null;
	}
	
	public void removeCharacterData(int characterID){
		final List<CharacterData> characterDatas = this.characterDatas;
		final int size = characterDatas.size();
		for (int i = 0; i < size; i++) {
			CharacterData character = characterDatas.get(i);
			if (character.getSheet().getCharacterID() == characterID) {
				characterDatas.remove(i);
				return;
			}
		}
	}

	public ApiSheet getCharacterSheet(int characterID) {
		final List<CharacterData> characterDatas = this.characterDatas;
		final int size = characterDatas.size();
		for (int i = 0; i < size; i++) {
			CharacterData character = characterDatas.get(i);
			final ApiSheet sheet = character.getSheet();
			if (sheet.getCharacterID() == characterID) {
				return sheet;
			}
		}
		return null;
	}
}
